package com.zuxia.utils;

import com.zuxia.entity.Point;

import java.util.ArrayList;
import java.util.List;

public class GeoUtils { // 地球半径，单位：米
    private static final double EARTH_RADIUS = 6371000;
    // 赤道上每度经度的距离，单位：米
    private static final double EQUATORIAL_CIRCUMFERENCE = 40075016.686; // 赤道周长，单位：米
    // 每度纬度在赤道上的距离，单位：米（这个值在纬度变化时会有所不同，但在这里作为近似）
    private static final double DISTANCE_PER_DEGREE_LATITUDE_AT_EQUATOR = EQUATORIAL_CIRCUMFERENCE / 360;

    // 将度转换为弧度
    private static double degreesToRadians(double degrees) {
        return degrees * Math.PI / 180;
    }

    // 计算给定纬度上每度经度的距离，单位：米
    private static double distancePerDegreeLongitude(double latitude) {
        return DISTANCE_PER_DEGREE_LATITUDE_AT_EQUATOR * Math.cos(degreesToRadians(latitude));
    }

    public static void main(String[] args) {
        double centerLat = 29.662655;
        double centerLng = 106.61801;
        double distanceKm = 20;
        Point point = new Point(29.650906,106.378567);
        System.out.println(isPointInPolygon(centerLat,centerLng,distanceKm,point));

    }

    private static double formatNum(double num,int size){
        return Double.parseDouble(String.format("%."+size+"f",num));
    }

    public static boolean isPointInPolygon(double centerLat, double centerLng, double distanceKm,Point point) {
        List<Point> polygon=new ArrayList<>();
        double latOffsetKm = distanceKm;
        double lngOffsetKm = distanceKm;

        double latOffsetDegrees = latOffsetKm / (DISTANCE_PER_DEGREE_LATITUDE_AT_EQUATOR / 1000); // 将公里转换为米，并计算纬度偏移量（度）
        double lngOffsetDegrees = lngOffsetKm / (distancePerDegreeLongitude(centerLat) / 1000); // 将公里转换为米，并根据给定纬度计算经度偏移量（度）

        int size1 = (point.getLatitude()+"").substring((point.getLatitude()+"").indexOf(".")+1).length();
        int size2 = (point.getLongitude()+"").substring((point.getLongitude()+"").indexOf(".")+1).length();

        // 计算四个顶点的坐标
        Point point1 = new Point(formatNum(centerLat + latOffsetDegrees,size1), formatNum(centerLng + lngOffsetDegrees,size2));// 左上角

        Point point2 = new Point(formatNum(centerLat + latOffsetDegrees,size1),  formatNum(centerLng - lngOffsetDegrees,size2));// 右上角

        Point point3 = new Point(formatNum(centerLat - latOffsetDegrees,size1), formatNum(centerLng + lngOffsetDegrees,size2));// 右下角

        Point point4 = new Point(formatNum(centerLat - latOffsetDegrees,size1), formatNum(centerLng - lngOffsetDegrees,size2));// 左下角


        polygon.add(point4);// 左下角
        polygon.add(point1);// 左上角
        polygon.add(point2);// 右上角
        polygon.add(point3);// 右下角

        for (int i = 0; i < polygon.size(); i++) {
            System.out.println(polygon.get(i));
        }

        // 计算边界
        double minLat = Double.MAX_VALUE, maxLat = Double.MIN_VALUE;
        double minLon = Double.MAX_VALUE, maxLon = Double.MIN_VALUE;

        for (Point corner : polygon) {
            minLat = Math.min(minLat, corner.getLatitude());
            maxLat = Math.max(maxLat, corner.getLatitude());
            minLon = Math.min(minLon, corner.getLongitude());
            maxLon = Math.max(maxLon, corner.getLongitude());
        }
        return point.getLatitude() >= minLat && point.getLatitude() <= maxLat &&
                point.getLongitude() >= minLon && point.getLongitude() <= maxLon;
    }
}
